home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / asm_msc1.arc / EX57.ASM < prev    next >
Assembly Source File  |  1988-11-20  |  4KB  |  111 lines

  1. TITLE  Add Entry to an Ordered List (EX57.ASM)
  2.           PAGE      ,132
  3. DATA      SEGMENT   PARA 'DATA'
  4. START_ADDR  DW      ?
  5. DATA      ENDS
  6. OUR_CODE  SEGMENT   PARA 'CODE'
  7.       PUBLIC    ADD_TO_OL
  8. ADD_TO_OL PROC      FAR
  9.           ASSUME    CS:OUR_CODE,DS:DATA
  10.       PUSH      DS             ;Save caller's registers
  11.       PUSH      CX
  12.       PUSH        SI             
  13.       PUSH        BX
  14.       MOV        BX,SEG DATA      ;Initialize DS
  15.           MOV       DS,BX
  16.       CALL        B_SEARCH         ;Is the value in the list?
  17.       JNC        GOODBYE         ; If so, exit
  18.       MOV        BX,SI         ; If not, copy compare addr. to Bx
  19.       MOV        CX,ES:[DI]         ;Find address of last element
  20.       SHL        CX,1
  21.       ADD        CX,DI         ; and put it in CX
  22.       PUSH        CX             ;Save this address on the stack
  23.       SUB        CX,SI         ;Calculate no. of words to be moved
  24.       SHR        CX,1
  25.       CMP        AX,ES:[SI]         ;Should compare el. be moved,too?
  26.       JA        EXCLUDE
  27.       INC        CX             ; Yes.  Increase move count by 1
  28.       JNZ         CHECK_CNT
  29. EXCLUDE:  ADD        BX,2         ; No.  Adjust insert pointer
  30. CHECK_CNT: CMP        CX,0         ;Move count = 0?
  31.       JNE        MOVE_ELS
  32.       POP        SI             ; If so, store value at end of list
  33.       MOV        ES:[SI+2],AX
  34.       JMP        SHORT INC_CNT    ;  then go increase element count
  35. MOVE_ELS: POP        SI             ;Load start address for move
  36.       PUSH        BX              ;Save insert address on stack
  37. MOVE_ONE: MOV        BX,ES:[SI]         ;Move one element down in list
  38.       MOV        ES:[SI+2],BX
  39.       SUB        SI,2         ;Point to next element
  40.       LOOP        MOVE_ONE         ;Repeat until all are moved
  41.       POP       BX             ;Retrieve insert address
  42.       MOV        ES:[BX],AX         ;Insert AX in the list
  43. INC_CNT:  INC        WORD PTR ES:[DI] ;Add 1 to element count
  44. GOODBYE:  POP        BX             ;Restore registers
  45.       POP        SI    
  46.       POP        CX
  47.       POP        DS
  48.       RET                 ; and exit
  49. ADD_TO_OL ENDP
  50. ;
  51. ;  This is the B_SEARCH procedure from Example 5-6.
  52. ;
  53. B_SEARCH  PROC
  54.       CMP        AX,ES:[DI+2]     ;Search value < or = first el.?
  55.       JA        CHK_LAST         ; No.  Go check last element
  56.       LEA        SI,ES:[DI+2]     ; Yes.  Fetch addr. of first el.
  57.       JE        EXIT_1ST         ;If value = 1st element, exit
  58.       STC                 ;If value < 1st element, set CF
  59. EXIT_1ST:  RET
  60. CHK_LAST: MOV        SI,ES:[DI]         ;Point to last element
  61.       SHL        SI,1
  62.       ADD        SI,DI
  63.       CMP        AX,ES:[SI]         ;Search value > or = last el.?
  64.       JB        SEARCH           ; No.  Go search list
  65.       JE        EXIT_LAST        ; Yes.  Exit if value = last el.
  66.       STC                 ;If value > last element, set CF
  67. EXIT_LAST: RET                       ;    and then exit
  68. ;
  69. ;  Search for value within the list.
  70. ;
  71. SEARCH:  MOV        START_ADDR,DI    ;Save starting address in memory
  72.       MOV        SI,ES:[DI]         ;Fetch index
  73. EVEN_IDX: TEST        SI,1         ;Force index to an even value
  74.       JZ        ADD_IDX
  75.       INC        SI
  76. ADD_IDX:  ADD        DI,SI         ;Calculate next search address
  77. COMPARE:  CMP        AX,ES:[DI]         ;Search value found?
  78.       JE        ALL_DONE         ; If so, exit
  79.       JA        HIGHER         ; Otherwise, find correct half
  80. ;
  81. ;  These instructions are executed if the search value is lower
  82. ;  in the list.
  83. ;
  84.       CMP        SI,2         ;Index = 2?
  85.       JNE        IDX_OK
  86. NO_MATCH: STC                 ; If so, set CF
  87.       JE        ALL_DONE         ;  and exit
  88. IDX_OK:   SHR        SI,1         ; If not, divide index by 2
  89.       TEST        SI,1         ;Force index to an even value
  90.       JZ        SUB_IDX
  91.       INC        SI
  92. SUB_IDX:  SUB        DI,SI         ;Calculate next address
  93.       JMP        SHORT COMPARE    ;Go check this element
  94. ;
  95. ;  These instructions are executed if the search value is higher
  96. ;  in the list.
  97. ;
  98. HIGHER:   CMP        SI,2         ;Index = 2?
  99.       JE        NO_MATCH         ; If so, go set CF and exit
  100.              SHR        SI,1         ; If not, divide index by 2
  101.       JMP        SHORT EVEN_IDX   ;Go check next element
  102. ;
  103. ;  Following are exit instructions.
  104. ;
  105. ALL_DONE: MOV       SI,DI         ;Move compare address into SI
  106.             MOV        DI,START_ADDR    ;Restore starting address
  107.            RET                 ; and exit
  108. B_SEARCH  ENDP
  109. OUR_CODE  ENDS
  110.          END       ADD_TO_OL
  111.